  <div id="preamble">

    <h3>Interacting with the Engine </h3>

    <h4>Codes</h4>
    <p>
      <a href="#codes">Shortcut</a>
      to one letter codes used in status format and update field requests.
    </p>

    <p>
      Updating physical machine statics or the administrative status of farms and physicals
      is done through GET queries to the engine. If the request produces output, either data
      or error message, it is delivered as content type plain text.
    </p>

    <h4>Dealing with URL escaping</h4>
    <p>
      If you desire to, or the web agent you are using does so automatically, you can
      inform the engine that query string containing all the argumetns is URL escaped.
      This is done by setting the first char of the query string to be "E".
      In general, this a pretty good idea because the format arguments are printf style,
      and ought to be escaped. 
    </p>
    <p>eg. <code>/ath/status/phys/?Eh=app01,f="%h,%c"</code> [expects everything after E to be url escaped]
    </p>

    <h4>Contructing a query piece by piece</h4>
    <p>
      These are listed in order of construction, with the "+" indicating what must come next, 
      which can be another access level in the engine are the end of the path and beginning of
      arguments.
      <ul>
	<li><b>Server Location</b>
	  <ul>
	    <li>eg. http://proxy.system.to + engine path</li>
	    <p>
	      The location of the server running the load balancer engine.
	      Proxy rules must be such that requests coming in on desired host:port 
	      interface are not passed to mod_proxy. You want to interact with the load
	      balancer engine, not be load balanced on this request.
	    </p>
	  </ul>
	</li>
	<li><b>Engine Path</b>
	  <ul>
	    <li>eg. /ath + request type</li>
	    <p>
	      The path on the apache instance that triggers the engine to take over the 
	      request. This is configurable via directive.
	    </p>
	  </ul>
	</li>
	<li><b>Engine Request Type</b>
	  <p>
	    Once the engine takes over the request, it will finish it, valid or not.
	    It looks for the following paths to determine what type of request it's been
	    sent.
	  </p>
	  <ul>
	    <li><b>/status</b></li> + subsystem
	    <p>
	      A status request is read only to the shared memory that contains the
	      state of all farms, physicals, and engine internal stats. It is used
	      to monitor or gather information about the runtime engine.
	      It requires a subsystem to differentiate what type of data is desired.
	      As arguments it takes desired entity and output format arguments.
	      The include script "ath_monitor.sh" uses it to monitor and report on
	      the health of your servers from the engine's perspective.
	    </p>
	    <li><b>/update</b></li> + subsystem
	    <p>
	      An update request is a privileged write request that updates the shared
	      memory representing the state of the load balancer. It is most used to 
	      update physical system performance metrics and farm and physical administrative
	      statuses. It requires a subsystem and then arguments clarifying which
	      entity and what field of that entity to update.
	      The included "ath_agent.sh" script uses it to update cpu and load
	      average. You can flag farms and physical systems online or offline, or report
	      physical systems as sick (this can also be done automatically, to some extent,
	      with the AthExpectUpdate logic, which will time out and flag down systems
	      who are failing to report in their status).
	    </p>
	    <li><b>/balance</b></li> + query args
	    <p>
	      A balance quest is used when a balancing decision is desired outside of 
	      reverse proxy request. For example, if your web application fires off
	      backgrounded heavy load processes, it is likely the the balancing decision
	      made to initiate the UI driven request is not the right one for the 
	      background thread. 
	      You may even want it to go to a different, non-web-enabled farm, using some
	      queueing system. You can query the engine for a decision on one or many farms,
	      and even ask it to use a different algorithm than the preconfigured one for that 
	      farm. When more than one farm is requested, the result is returned new-line
	      separated in the same order the query requested them. If all members of a
	      farm are unavailable, it will say 
	      <code>WARNING: FARM: NO MEMBER AVAILABLE</code>.
	      If the farm is invalid, it will say <code>WARNING: FARM NOT CONFIGURED</code>.
	    </p>
	    <ul> <b>Arguments</b>
	      <li><code>:</code> joins an algorithm substitution to the farm requested</li>
	      <li><code>,</code> joins multiple farm(:algo) requests</li>
	    </ul>
	    <p>eg. <code>/ath/balance/?FARM1</code>
	    </p>
	    <p>eg. <code>/ath/balance/?FARM1,FARM2,FARM3</code>
	    </p>
	    <p>eg. <code>/ath/balance/?FARM1:dynamic-cpu-mem</code>
	    </p>
	    <li><b>/mirror</b></li> + subsystem + query args
	    <p>
	      This is used to mirror the state of one load balancer to another identically
	      configured (in farms and physicals (farm members)) load balancer. 
	      The mirror request is sent to update the system that is slave to the primary.
	      It updates more fields than the "/update" type allows.
	      This request type can be completely disabled by directive.
	      It may
	      prove useful in some installations. The authors installation used to use this,
	      but it requires the primary to be healthy in most use cases, so he switched
	      to running 2 completely independent systems, and just sends updates to both
	      from each member.
	    </p>
	    <p>
	      It requires a subsystem request, "/farm" or "/phys", followed by one 
	      argument, a serialized representation of one entity of that subsystem.
	      The serialized representation of an entity can be retrieved using 
	      a status request with output format specified as serialized. You can mirror
	      a farm or a phys. Mirroring a farm does NOT mirror the state of the
	      members of the farm, just all the data unique to the farm itself.
	      To completely mirror an engine, you need to mirror all farms and all physicals.
	    </p>
	    <p>
	      eg. <code>/ath/mirror/farm/?SERIALIZED_FARM_STRING</code>
	    </p>
	    <li>/hello</li>
	    <p>
	      Simply returns "hello". Use it verify that the engine is loaded and enabled.
	    </p>
	  </ul>
	</li>
	<li><b>Engine Request Target Subsystem</b>
	  <ul>
	    <li><b>/farm</b></li> + query args
	    <p>
	      Used for interacting with the farm subsystem.
	      In status context, you specify which entities you want to get data from,
	      then the output format of that data.
	      A farm entity is handled by its "name". Out put for more than one is new 
	      line separated.
	    </p>
	    <p>
	      <b>Status format AND update parameters use the same one letter code to indicate
		the relevant field. Format letter code is always preceded by "%".</b>
	    </p>
	    <ul><b>Status context parameters</b>, set with "=" separated by ","
	      <li>n</li> use once or more to specify entity by name, * is all
	      <li>f</li> use once to specify format, applies to all names requested
	    </ul>
	    <p>eg. <code>/ath/status/farm?n=FARM</code> [outputs default readable detail]</p>
	    <p>eg. <code>/ath/status/farm?n=FARM-A,FARM-B</code> [outputs default readable detail for 2 farms, new line separated]</p>
	    <p>eg. <code>/ath/status/farm?n=FARM,f=%m</code> [outputs just its member physical handles]</p>
	    <ul><b>Update context parameters</b>, set with "=" separated by ","
	      <li>n</li> use once or more to specify entity by name, * is all
	      <li>for the fields, see <a href="#codesfarm">farm codes</a></li>
	    </ul>
	    <p>
	      eg. <code>/ath/update/farm/?n=FARM,o=1</code> [sets FARM to online]
	    </p>
	    <li><b>/phys</b></li> + query args
	    <p>
	      Used for interacting with the physical (farm members) subsystem.
	      In status context, you specify which entities you want to get data from,
	      then the output format of that data.
	      A phys entity is handled by its "hostname". Out put for more than one is new 
	      line separated. In reality a "hostname" can actually be the concatenation of
	      a hostname and a port, eg. <code>app01:8080</code>.
	    </p>
	    <p>
	      <b>Status format AND update parameters use the same one letter code to indicate
		the relevant field. Format letter code is always preceded by "%".</b>
	    </p>
	    <ul><b>Status context paramameters</b>
	      <li>h</li> use once or more to specify entity by hostname, * is all
	      <li>f</li> use once to specify format of ouput, applies to all entities
	    </ul>
	    <ul><b>Update context parameters</b>
	      <li>h</li>
	      <li>for fields see <a href="#codesphys">phys codes</a></li>
	    </ul>
	    <p>
	      eg. <code>/status/phys/?h=app01,f=%c</code> [outputs cpu load of app01]
	    </p>
	    <p>
	      eg. <code>/status/phys/?h=app01</code> [outputs default data, which is everything in readable format]
	    </p>
	    <li>/engine</li> + query args
	  </ul>
      </ul>

      <a name="codes"></a>
      <a name="codesfarm"></a>
      <h4>Farm codes</h4>

      <ul>
	<li>n</li> name
      </ul>

      <a name="codesphys"></a>
      <h4>Phys codes</h4>


  </div>

</div>

